package com.softer.wxzj.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.softer.wxzj.common.entity.CommonResult;
import com.softer.wxzj.common.entity.Page;
import com.softer.wxzj.common.enums.MessageEnum;
import com.softer.wxzj.common.enums.NumStrEnum;
import com.softer.wxzj.common.enums.NumberEnum;
import com.softer.wxzj.common.enums.ShiroResultEnum;
import com.softer.wxzj.common.error.CourseException;
import com.softer.wxzj.common.flow.enums.FlowTypeEnum;
import com.softer.wxzj.common.util.ModifyUtil;
import com.softer.wxzj.common.util.ShiroUserUtil;
import com.softer.wxzj.common.util.StringUtils;
import com.softer.wxzj.common.util.UUIDUtil;
import com.softer.wxzj.entity.*;
import com.softer.wxzj.mapper.BaseBankInfoMapper;
import com.softer.wxzj.mapper.DicContentMapper;
import com.softer.wxzj.mapper.OrgBankInfoMapper;
import com.softer.wxzj.service.BaseOrganizationService;
import com.softer.wxzj.service.BaseOwnerCommitteeService;
import com.softer.wxzj.service.OrgBankInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Gong Zhiyang
 * @date 2019/7/12
 */
@Service
public class OrgBankInfoServiceImpl implements OrgBankInfoService {
    @Autowired
    private OrgBankInfoMapper orgBankInfoMapper;
    @Autowired
    private ModifyUtil modifyUtil;
    @Autowired
    private BaseOrganizationService baseOrganizationService;
    @Autowired
    private BaseOwnerCommitteeService baseOwnerCommitteeService;
    @Autowired
    private FileServiceImpl fileService;
    @Autowired
    private BaseBankInfoMapper baseBankInfoMapper;
    @Autowired
    private DicContentMapper dicContentMapper;

    /**
     * 物业银行账号新增
     *
     * @param orgBankInfo 银行账号
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult add(OrgBankInfo orgBankInfo) {
        String uuid = UUIDUtil.getUUID();
        orgBankInfo.setId(uuid);
        if (StringUtils.isBlank(orgBankInfo.getRepDate())) {
            orgBankInfo.setRepDate(null);
        }
        //查询添加的银行是否存在使用中的，如果不存在，则默认开启，如果存在，则默认停用状态
        String id = orgBankInfoMapper.getOrgBankByBankIdAndState(orgBankInfo);
        if (StringUtils.isNotEmpty(id)) {
            orgBankInfo.setState(String.valueOf(NumberEnum.ZERO.getNum()));
        } else {
            orgBankInfo.setState(String.valueOf(NumberEnum.ONE.getNum()));
        }
        int num = orgBankInfoMapper.insert(orgBankInfo);
        if (num <= 0) {
            return CommonResult.ResponseResult(num);
        }
        //保存图片
        CommonResult commonResult = fileService.addFile(orgBankInfo.getFileTypeList(), uuid);
        if (ShiroResultEnum.FAIL.getCode() == commonResult.getData()) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), commonResult.getMessage());
        }
        return CommonResult.idResult(num, uuid);
    }

    /**
     * 启用/停用账号 1启用，0停用
     *
     * @param id    账号ID
     * @param state 1启用，0停用
     * @return 修改结果
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public CommonResult updateState(String id, String state) {
        // 如果是启用的话，则该银行的其他账号需要停用
        String userName = ShiroUserUtil.getUserName();
        if (String.valueOf(NumberEnum.ONE.getNum()).equals(state)) {
            //该银行的其他账号需要停用
            orgBankInfoMapper.stopBankInfo(id, userName);
        }
        return CommonResult.ResponseResult(orgBankInfoMapper.updateState(id, state, userName));
    }

    /**
     * 查询某个物业企业下的所有账号
     *
     * @param page        分页实体
     * @param orgBankInfo 查询实体
     * @return 账号列表
     */
    @Override
    public PageInfo<OrgBankInfo> getOrgBankInfoList(Page page, OrgBankInfo orgBankInfo) {
        List<OrgBankInfo> list;
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        if (StringUtils.isNotEmpty(orgBankInfo.getFuzzy())) {
            //模糊查询
            list = orgBankInfoMapper.fuzzyOrgBankInfoList(orgBankInfo.getFuzzy(), orgBankInfo.getOrgId());
        } else {
            //精确查询
            list = orgBankInfoMapper.getOrgBankInfoList(orgBankInfo);
        }
        return new PageInfo<>(list);
    }

    /**
     * 查询详情
     *
     * @param id      账号ID
     * @param arcType 图档大类
     * @return 详情
     */
    @Override
    public OrgBankInfo getInfo(String id, String arcType) {
        OrgBankInfo orgBankInfo = orgBankInfoMapper.selectByPrimaryKey(id);
        // 查询图档信息
        List<FileVO> fileVOList = fileService.getFileVOList(id, arcType);
        orgBankInfo.setFileTypeList(fileVOList);
        return orgBankInfo;
    }

    /**
     * 修改物业企业账号
     *
     * @param orgBankInfo 账号实体
     * @param reason      变更说明
     * @return 修改结果
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public CommonResult update(OrgBankInfo orgBankInfo, String reason) {
        OrgBankInfo beforeInfo = getInfo(orgBankInfo.getId(), null);
        String uuid = UUIDUtil.getUUID();
        int num;
        try {
            if (!orgBankInfo.getBankId().equals(beforeInfo.getBankId()) && NumStrEnum.ONE.getNum().equals(beforeInfo.getState())) {
                //如果修改了开户银行
                //如果当前账号是启用状态，则停用修改后的银行的其他账户
                //该银行的其他账号需要停用
                orgBankInfoMapper.stopBankInfoByBankId(orgBankInfo.getBankId(), ShiroUserUtil.getUserName());
            }
            num = modifyUtil.updateToSave(beforeInfo, orgBankInfo, orgBankInfo.getId(), FlowTypeEnum.ORG_BANK.getType(), reason, uuid);
            // 图档变更操作
            int fileNum = fileService.modifyFile(orgBankInfo.getFileTypeList(), orgBankInfo.getId(), FlowTypeEnum.ORG_BANK.getType(), reason, uuid);
            dealUpdate((num + fileNum), orgBankInfo);

        } catch (IllegalAccessException e) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), MessageEnum.FAIL.getMsg());
        }

        return CommonResult.ResponseResult(1);
    }

    /**
     * 外网调用，修改物业企业账号
     *
     * @param orgBankInfo 账号实体
     * @return 修改结果
     */
    @Override
    @Transactional(rollbackFor = {RuntimeException.class, Exception.class})
    public CommonResult updateOrg(OrgBankInfo orgBankInfo) {
        OrgBankInfo beforeInfo = getInfo(orgBankInfo.getId(), null);
        String uuid = UUIDUtil.getUUID();
        int num;
        try {
            if (!orgBankInfo.getBankId().equals(beforeInfo.getBankId()) && NumStrEnum.ONE.getNum().equals(beforeInfo.getState())) {
                //如果修改了开户银行
                //如果当前账号是启用状态，则停用修改后的银行的其他账户
                //该银行的其他账号需要停用
                orgBankInfoMapper.stopBankInfoByBankId(orgBankInfo.getBankId(), orgBankInfo.getOperNo());
            }
            num = modifyUtil.orgUpdate(beforeInfo, orgBankInfo, orgBankInfo.getId(), FlowTypeEnum.ORG_BANK.getType(), orgBankInfo.getReason(), uuid, orgBankInfo.getOperNo());
            // 图档变更操作
            int fileNum = fileService.modifyFile(orgBankInfo.getFileTypeList(), orgBankInfo.getId(), FlowTypeEnum.ORG_BANK.getType(), orgBankInfo.getReason(), uuid);
            dealUpdate((num + fileNum), orgBankInfo);

        } catch (IllegalAccessException e) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), MessageEnum.FAIL.getMsg());
        }
        return CommonResult.ResponseResult(1);
    }

    /**
     * 外网查询收款账号变更详情
     *
     * @param id 收款账号ID（也是变更表中的业务ID）
     * @return 收款账号变更详情列表
     */
    @Override
    public PageInfo<BaseModifyDetail> getModifyDetailList(Page page, String id) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        List<BaseModifyDetail> list = orgBankInfoMapper.getModifyDetailList(id);
        dealList(list);
        return new PageInfo<>(list);
    }

    /**
     * 处理部分ID数据,转换为中文
     *
     * @param list 变更list
     */
    private void dealList(List<BaseModifyDetail> list) {
        for (BaseModifyDetail baseModifyDetail : list) {
            String name = baseModifyDetail.getColumnName();
            switch (name) {
                case "bankId":
                    String newBankName = baseBankInfoMapper.getBankName(baseModifyDetail.getNewValue());
                    String oldBankName = baseBankInfoMapper.getBankName(baseModifyDetail.getOldValue());
                    baseModifyDetail.setNewValue(null == newBankName ? "" : newBankName);
                    baseModifyDetail.setOldValue(null == oldBankName ? "" : oldBankName);
                    break;
                case "certType":
                    String newCertName = dicContentMapper.selectName(baseModifyDetail.getNewValue());
                    String oldCertName = dicContentMapper.selectName(baseModifyDetail.getOldValue());
                    baseModifyDetail.setNewValue(null == newCertName ? "" : newCertName);
                    baseModifyDetail.setOldValue(null == oldCertName ? "" : oldCertName);
                    break;
                default:
                    break;
            }
        }
    }

    public void dealUpdate(int num, OrgBankInfo orgBankInfo) {
        if (num > NumberEnum.ZERO.getNum()) {
            if (StringUtils.isBlank(orgBankInfo.getRepDate())) {
                orgBankInfo.setRepDate(null);
            }
            int count = orgBankInfoMapper.updateByPrimaryKey(orgBankInfo);
            if (count == NumberEnum.ZERO.getNum()) {
                throw new CourseException(ShiroResultEnum.FAIL.getCode(), "变更失败");
            }
            //处理图片修改
            CommonResult result = fileService.updateFile(orgBankInfo.getFileTypeList(), orgBankInfo.getId());
            if (ShiroResultEnum.FAIL.getCode() == result.getData()) {
                throw new CourseException(ShiroResultEnum.FAIL.getCode(), result.getMessage());
            }
        } else {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), "没有修改信息");
        }
    }

    /**
     * 根据ID查询变更记录
     *
     * @param page          分页实体
     * @param baseModifyReq 查询实体   账号ID（也是变更表中的业务ID）
     * @return 变更记录列表
     */
    @Override
    public PageInfo<BaseModifyReq> getReqListById(Page page, BaseModifyReq baseModifyReq) {
        List<BaseModifyReq> list;
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        if (StringUtils.isNotEmpty(baseModifyReq.getFuzzy())) {
            //模糊查询
            list = orgBankInfoMapper.fuzzyReqListById(baseModifyReq.getId(), baseModifyReq.getFuzzy());
        } else {
            //精确查询
            list = orgBankInfoMapper.getReqListById(baseModifyReq);
        }
        return new PageInfo<>(list);
    }

    @Override
    public List<OrgBankInfo> getList() {
        return orgBankInfoMapper.getList();
    }

    /**
     * 获取企业下可以账号列表
     *
     * @param id 企业ID
     * @return 银行账户列表
     */
    @Override
    public List<OrgBankInfo> getOrgBankAccount(String id) {
        return orgBankInfoMapper.getOrgBankAccount(id);
    }

    /**
     * 新增物业企业和企业银行账户
     *
     * @param organization 物业企业信息
     * @param orgBankInfo  银行账户信息
     * @return 新增结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult addCorpAndOrgBank(BaseOrganization organization, OrgBankInfo orgBankInfo) {
        //新增物业企业，id用于保存企业id
        CommonResult insert = baseOrganizationService.insert(organization);
        if (ShiroResultEnum.FAIL.getCode() == insert.getData()) {
            return insert;
        }
        orgBankInfo.setOrgId(insert.getId());
        //新增银行账户信息
        CommonResult add = add(orgBankInfo);
        if (ShiroResultEnum.FAIL.getCode() == add.getData()) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), add.getMessage());
        }
        //将银行账户ID保存返回
        insert.setOrgBankId(add.getId());
        return insert;
    }

    /**
     * 修改物业企业和企业银行账户
     *
     * @param organization 物业企业信息
     * @param orgBankInfo  银行账户信息
     * @return 修改结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult updateCorpAndOrgBank(BaseOrganization organization, OrgBankInfo orgBankInfo) {
        CommonResult update = baseOrganizationService.update(organization);
        CommonResult commonResult = updateOrgBank(update, orgBankInfo);
        if (ShiroResultEnum.FAIL.getCode() == commonResult.getData()) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), commonResult.getMessage());
        }
        return update;
    }

    /**
     * 新增业委会和企业银行账户
     *
     * @param baseOwnerCommittee 业委会信息
     * @param orgBankInfo        银行账户信息
     * @return 新增结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult addCommitteeAndOrgBank(BaseOwnerCommittee baseOwnerCommittee, OrgBankInfo orgBankInfo) {
        CommonResult committee = baseOwnerCommitteeService.insertToId(baseOwnerCommittee);
        if (ShiroResultEnum.FAIL.getCode() == committee.getData()) {
            return committee;
        }
        orgBankInfo.setOrgId(committee.getId());
        //新增银行账户信息
        CommonResult add = add(orgBankInfo);
        if (ShiroResultEnum.FAIL.getCode() == add.getData()) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), add.getMessage());
        }
        //将银行账户ID保存返回
        committee.setOrgBankId(add.getId());
        return committee;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResult updateCommitteeAndOrgBank(BaseOwnerCommittee baseOwnerCommittee, OrgBankInfo orgBankInfo) {
        CommonResult update = baseOwnerCommitteeService.update(baseOwnerCommittee);
        CommonResult commonResult = updateOrgBank(update, orgBankInfo);
        if (ShiroResultEnum.FAIL.getCode() == commonResult.getData()) {
            throw new CourseException(ShiroResultEnum.FAIL.getCode(), commonResult.getMessage());
        }
        return update;
    }

    /**
     * 根据项目ID查询该项目的收款单位
     *
     * @param id 拨款ID
     * @return 收款单位集合（申请单位和施工单位）
     */
    @Override
    public List<Map<String, String>> getOrgByReqId(String id) {
        List<Map<String, String>> list = new ArrayList<>();
        BaseOrganization baseOrganization = orgBankInfoMapper.getOrgByReqId(id);
        if (baseOrganization != null) {
            if (StringUtils.isNotEmpty(baseOrganization.getOrgName())) {
                addList(list, baseOrganization.getBusinessId(), baseOrganization.getOrgName());
            }
            if (StringUtils.isNotEmpty(baseOrganization.getOrgTypeCode())) {
                addList(list, baseOrganization.getModifyId(), baseOrganization.getOrgTypeCode());
            }
            if (StringUtils.isNotEmpty(baseOrganization.getOrgBirefName())) {
                addList(list, baseOrganization.getId(), baseOrganization.getOrgBirefName());
            }
        }
        return list;
    }

    private void addList(List<Map<String, String>> list, String id, String name) {
        Map<String, String> map = new HashMap<>(5);
        map.put("id", id);
        map.put("name", name);
        list.add(map);
    }

    /**
     * 修改拨款账户
     *
     * @param orgBankInfo 拨款账户
     * @return 修改结果
     */
    private CommonResult updateOrgBank(CommonResult update, OrgBankInfo orgBankInfo) {
        if (ShiroResultEnum.FAIL.getCode() == update.getData()) {
            return update;
        }
        if (StringUtils.isEmpty(orgBankInfo.getOrgBankId())) {
            return CommonResult.ResponseResult(NumberEnum.ZERO.getNum(), "未传拨款账户ID");
        }
        orgBankInfo.setId(orgBankInfo.getOrgBankId());
        int num = orgBankInfoMapper.updateByPrimaryKey(orgBankInfo);
        if (num == NumberEnum.ZERO.getNum()) {
            return CommonResult.ResponseResult(NumberEnum.ZERO.getNum(), MessageEnum.FAIL.getMsg());
        }
        return CommonResult.ResponseResult(NumberEnum.ONE.getNum());
    }
}
